from twisted.internet import reactor
from twisted.python import log
from eDIP43A_Display import eDIP43A_Display
from eDIP43A_Async import eDIP43A_Async
from spConstants import *

BAR_VOLUME = 1
VOLUME_PLUS = 45
VOLUME_MINUS = 43

CALL_FREQUENCY = 1

########################################################################
class eDIP43A_AsyncDisplay(eDIP43A_Display, eDIP43A_Async):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, factory):
        """Constructor"""
        eDIP43A_Display.__init__(self, on_touch=self.on_touch, on_bargraph=self.on_bargraph, on_input=self.on_input)
        eDIP43A_Async.__init__(self)
        self.factory = factory
        print "constructor for Async_Display"

    #----------------------------------------------------------------------
    def send_Command(self, buffer, payload=False, protocol=False):
        """"""
        # execute returns a deferred
        d = self.execute(buffer, payload=payload, protocol=protocol)
        return d        

    def connectionMade(self):
        """
        """
        eDIP43A_Async.connectionMade(self)
        log.msg("super class connection made")        
        self.readVolume()
    
    #----------------------------------------------------------------------
    def readVolume(self):
        """"""
        buffer = self.eDIP_BS(BAR_VOLUME)
        d = self.send_Command(buffer)
        d.addBoth(self.sendCommandCallback)
        
    #----------------------------------------------------------------------
    def sendCommandCallback(self, result):
        """"""
        res, buff = result
        if(res==ACK):
            self.CheckDataBuffer()
        else:
            self.readVolume()
            

    def on_touch(self, code):
        """
        """
        log.msg("on_touch: " + str(code))
        if(code==VOLUME_PLUS):
            self.VolumeUp()
        elif(code==VOLUME_MINUS):
            self.VolumeDown()
    
    #----------------------------------------------------------------------
    def VolumeUp(self):
        """"""
        self.factory.setVolumeUp()
        buffer = self.eDIP_BA(BAR_VOLUME, self.factory.volume)
        d = self.send_Command(buffer)
        d.addBoth(self.volumeCallback)
    
    #----------------------------------------------------------------------
    def VolumeDown(self):
        """"""
        self.factory.setVolumeDown()
        buffer = self.eDIP_BA(BAR_VOLUME, self.factory.volume)
        d = self.send_Command(buffer)
        d.addBoth(self.volumeCallback)       
    
    #----------------------------------------------------------------------
    def volumeCallback(self, result):
        """"""
        
        
        
    #----------------------------------------------------------------------
    def on_bargraph(self, barNo, value):
        """"""
        log.msg("Bargraph no: " + str(barNo) + " Value: "+ str(value))
        if(barNo==BAR_VOLUME):
            self.factory.volume = value
        
    #----------------------------------------------------------------------
    def on_input(self, inputs):
        """"""
        log.msg("Value: " + str(bin(inputs)))
        if(isBitSet(inputs, 7)):
            self.VolumeUp()
        elif(isBitSet(inputs, 0)):
            self.VolumeDown()
        else:
            log.msg("no coded yet")
    #----------------------------------------------------------------------
    def CheckDataBuffer(self):
        """
            Checks if any data in buffer
        """
        d = self.request_Information_Buffer()
        d.addCallback(self.DataBufferCallback)        
        d.addErrback(self.DataBufferErrorback)

    def DataBufferCallback(self, result):
        """"""
        ack, buffer = result
        ready, free = buffer
        #log.msg("No Data in buffer: " + str(ready) + " - No free bytes: " + str(free))
        if(ready>0):
            self.ReadDataBuffer();
        else:
            reactor.callLater(CALL_FREQUENCY, self.CheckDataBuffer)

    def DataBufferErrorback(self, reason):
        """ Data buffer errorback
        """
        log.msg("Data buffer error back")
        reactor.callLater(CALL_FREQUENCY, self.CheckDataBuffer)

    #----------------------------------------------------------------------
    def ReadDataBuffer(self):
        """ Read information from buffer
        """
        d = self.request_Content_Buffer()
        d.addCallback(self.ReadBufferCallback)        
        d.addErrback(self.ReadBufferErrorback)        

    def ReadBufferCallback(self, result):
        """ Analise data from buffer
        """
        #log.msg(" Data from buffer: " + result)
        ack, ddata1 = result
        self.DecodeBuffer(ddata1)
        reactor.callLater(CALL_FREQUENCY, self.CheckDataBuffer)

    def ReadBufferErrorback(self, reason):
        """ Read buffer error
        """
        log.msg("Read buffer error: " )
        reactor.callLater(CALL_FREQUENCY, self.CheckDataBuffer)

    






